grammar laban;

options 
{
    k = 2; 
    backtrack = true; 
    memoize = true;
    language = C;
}

@lexer::includes {
	#include <laban.h>
}

@lexer::members  {
	extern DAGedges DAG;
	int cnt = BIGVAL;

	string toStr(const ANTLR3_STRING_struct* mstr) {
		return string((const char*) mstr->chars, mstr->len);
	}
	int toInt(const ANTLR3_STRING_struct* mstr) {
		return atoi((const char*) mstr->chars);
	}
}

decl	: (ASSIG|FUNCT)+ 
	;

ASSIG	: 'server' SPACER+ SERVER SPACER+
	| 'provider' SPACER+ PROVIDER SPACER+
	| 'client' SPACER+ CLIENT SPACER+
	| 'products' SPACER+ PRODUCTS SPACER+
	| 'item' SPACER+ ITEM SPACER+  
	;

FUNCT	: 'connect' SPACER+ node1=INT SPACER+ 'to' SPACER+ node2=INT SPACER+ {
			DAG.push_back(make_pair(make_pair("connect", cnt), make_pair(toStr($node1.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("connect", cnt), make_pair(toStr($node2.text),UNIQUEID)));
			cnt++;
		}
	| 'request' SPACER+ 'from' SPACER+ provider=INT SPACER+ 'to' SPACER+ client=INT SPACER+ {
			DAG.push_back(make_pair(make_pair("request", cnt), make_pair(toStr($provider.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("request", cnt), make_pair(toStr($client.text),UNIQUEID)));
			cnt++;
		}
	| 'sendplist' SPACER+ 'to' SPACER+ client=INT SPACER+ {
			DAG.push_back(make_pair(make_pair("sendplist", cnt), make_pair(toStr($client.text),UNIQUEID)));
		}
	| 'sendinfo' SPACER+ 'from' SPACER+ client=INT SPACER+ 'to' SPACER+ provider=INT SPACER+ {
			DAG.push_back(make_pair(make_pair("sendinfo", cnt), make_pair(toStr($client.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("sendinfo", cnt), make_pair(toStr($provider.text),UNIQUEID)));
			cnt++;
		}
	| 'order' SPACER+ item=INT SPACER+ 'from' SPACER+ provider=INT SPACER+ 'to' SPACER+ client=INT SPACER+ {
			DAG.push_back(make_pair(make_pair("order", cnt), make_pair(toStr($item.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("order", cnt), make_pair(toStr($provider.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("order", cnt), make_pair(toStr($client.text),UNIQUEID)));
			cnt++;
		}
	| 'confirm' SPACER+ 'from' SPACER+ provider=INT SPACER+ 'to' SPACER+ client=INT SPACER+ {
			DAG.push_back(make_pair(make_pair("confirm", cnt), make_pair(toStr($provider.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("confirm", cnt), make_pair(toStr($client.text),UNIQUEID)));
			cnt++;
		}
	;

SERVER	:  '{' SPACER* id=INT SPACER+ name=STRING SPACER+ usernum=INT SPACER* '}' {
			DAG.push_back(make_pair(make_pair("server", toInt($id.text)), make_pair(toStr($id.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("server", toInt($id.text)), make_pair(toStr($name.text),NONUNIQUEVAL)));
			DAG.push_back(make_pair(make_pair("server", toInt($id.text)), make_pair(toStr($usernum.text),NONUNIQUEVAL)));
		}
	;

PROVIDER: '{' SPACER* id=INT SPACER+ name=STRING SPACER+ phonenums=STRARRAY SPACER+ addresses=STRARRAY SPACER+ productsid=INT SPACER* '}' {
			DAG.push_back(make_pair(make_pair("provider", toInt($id.text)), make_pair(toStr($id.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("provider", toInt($id.text)), make_pair(toStr($name.text),NONUNIQUEVAL)));
			DAG.push_back(make_pair(make_pair("provider", toInt($id.text)), make_pair(toStr($phonenums.text),NONUNIQUEVAL)));
			DAG.push_back(make_pair(make_pair("provider", toInt($id.text)), make_pair(toStr($addresses.text),NONUNIQUEVAL)));
			DAG.push_back(make_pair(make_pair("provider", toInt($id.text)), make_pair(toStr($productsid.text),UNIQUEID)));
		}
	;


PRODUCTS: '{' SPACER* productsid=INT SPACER* '[' SPACER* itemid=INT {
			DAG.push_back(make_pair(make_pair("products", toInt($productsid.text)), make_pair(toStr($productsid.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("products", toInt($productsid.text)), make_pair(toStr($itemid.text),UNIQUEID)));
		} (SPACER+ itemids=INT {
			DAG.push_back(make_pair(make_pair("products", toInt($productsid.text)), make_pair(toStr($itemids.text),UNIQUEID)));
		})* SPACER* ']' SPACER* '}'
	;

ITEM	: '{' SPACER* id=INT SPACER+ name=STRING SPACER+ price=INT SPACER+ desc=STRING SPACER+ qty=INT SPACER* '}' {
			DAG.push_back(make_pair(make_pair("item", toInt($id.text)), make_pair(toStr($id.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("item", toInt($id.text)), make_pair(toStr($name.text),NONUNIQUEVAL)));
			DAG.push_back(make_pair(make_pair("item", toInt($id.text)), make_pair(toStr($price.text),NONUNIQUEVAL)));
			DAG.push_back(make_pair(make_pair("item", toInt($id.text)), make_pair(toStr($desc.text),NONUNIQUEVAL)));
			DAG.push_back(make_pair(make_pair("item", toInt($id.text)), make_pair(toStr($qty.text),NONUNIQUEVAL)));
		}
	;

CLIENT	: '{' SPACER* id=INT SPACER+ name=STRING SPACER+ phonenums=STRARRAY SPACER+ addresses=STRARRAY SPACER* '}' {
			DAG.push_back(make_pair(make_pair("client", toInt($id.text)), make_pair(toStr($id.text),UNIQUEID)));
			DAG.push_back(make_pair(make_pair("client", toInt($id.text)), make_pair(toStr($name.text),NONUNIQUEVAL)));
			DAG.push_back(make_pair(make_pair("client", toInt($id.text)), make_pair(toStr($phonenums.text),NONUNIQUEVAL)));
			DAG.push_back(make_pair(make_pair("client", toInt($id.text)), make_pair(toStr($addresses.text),NONUNIQUEVAL)));
		}
	;
	
STRARRAY 
	: '[' SPACER* STRING (SPACER+ STRING)* SPACER* ']'	
	;
	
SPACER	:' '|'\n'|'\r\n'
	;

INT :	'0'..'9'+
    ;

COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;
